package mapEditor.obj;

import debug.*;

import mapEditor.svg.SVGDOMTree;
import mapEditor.utils.MapLocation;
import mapEditor.utils.SvgFont;
import mapEditor.utils.SvgFill;
import mapEditor.utils.SvgStroke;
import mapEditor.utils.Util;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Dimension;
//import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Toolkit;
//import java.awt.font.LineMetrics;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.geom.AffineTransform;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JPanel;

import org.w3c.dom.svg.SVGTextElement;


// DOC: http://www.w3.org/TR/SVG11/text.html
// DOC: http://www.w3.org/TR/SVG11/text.html#TextElement
// DOC: http://www.zvon.org/xxl/svgReference/Output/el_text.html
public class TextObject extends DrawObject
{ //protected static final boolean USE_AnimatedLength=false; // OVERRIDE (to make updateSVGElement work)
	
  private double ANGLE=0;	
  private String TEXT="";
  public String getText() { return(TEXT); }
  protected void setText(String newValue)
  { if(!TEXT.equals(newValue))
    { String oldValue=TEXT; TEXT=newValue;
      justifySecondPoint();
      FIRE_CHANGE_EVENT("TEXT["+oldValue+"==>"+newValue+"]");
    }
  }
  
  public TextObject(SVGDOMTree domTree,MapLocation p1)
  { super(domTree,domTree.appendSVGTextElement());
    stroke.setEnabled(true);
	add(p1); add(p1.copy());
	justifySecondPoint();
  }
  
  public TextObject(SVGDOMTree domTree,SVGTextElement svgElement)
  { super(domTree,svgElement);
	decodeSVG(svgElement);
  }
  
  private int getStringWidth(String s)
  { FontMetrics fontMetrics=Toolkit.getDefaultToolkit().getFontMetrics(font.getFont()); 
	int width=fontMetrics.stringWidth(s);
	return(width);
  }
  
  private double getStringWidth(Graphics2D g,String s)
  { FontRenderContext frc=g.getFontRenderContext();
	Rectangle2D rect=font.getFont().getStringBounds(TEXT,frc); 
	double width=rect.getWidth();
	Debug.TRACE("TextObject.getStringWidth: "+s+", width="+width+", OLD width="+getStringWidth(s));
	return(width);
  }
  
  
  private void justifySecondPoint()
  {	MapLocation p0=getMapLocation(0);
	MapLocation p1=getMapLocation(1);
    int w=getStringWidth(getText());
    double theta=getAngle();
//      double dx=w*Math.sin(theta);
//      double dy=w*Math.cos(theta);
    double dy=w*Math.sin(theta);
    double dx=w*Math.cos(theta);
    Debug.TRACE("TextObject.updateLocation2: w="+w+", dx="+dx+", dy="+dy+", rad="+theta+", deg="+Math.toDegrees(theta));
    p1.setX(p0.getX()+dx); // TODO: TEST	
    p1.setY(p0.getY()+dy); // TODO: TEST	
  }
  
  public void decodeSVG(SVGTextElement svgElement)
  { Debug.TRACE("TextObject.decodeSVG: svgElement="+svgElement);
    String atr=svgElement.getAttribute("id"); if(atr.length()>0) this.setIdent(atr);
    this.font=new SvgFont(svgElement);
    this.fill=new SvgFill(svgElement);
    this.stroke=new SvgStroke(svgElement);
    clearPointSet();
    double x=0; atr=svgElement.getAttribute("x"); if(atr.length()>0) x=Double.parseDouble(atr);
    double y=0; atr=svgElement.getAttribute("y"); if(atr.length()>0) y=Double.parseDouble(atr);
    TEXT=svgElement.getTextContent();
    String transform=svgElement.getAttribute("transform");
    if(transform.length()>0)
    { // TODO: AD'HOC
      // transform="translate(304.0,507.0) rotate(13.4611485521254)" 
      Debug.TRACE("TextObject.decodeSVG: transform="+transform);
      if(transform.startsWith("translate("))
      { String s=transform.substring(10);
        int idx=s.indexOf(',');
        String X=s.substring(0,idx);
        s=s.substring(idx+1);
        idx=s.indexOf(')');
        String Y=s.substring(0,idx);
        s=s.substring(idx+1).trim();
        Debug.TRACE("TextObject.decodeSVG: X="+X+", Y="+Y+", RESTEN="+s);
        x=Double.parseDouble(X);
        y=Double.parseDouble(Y);
        if(s.startsWith("rotate("))
        { s=s.substring(7);
          idx=s.indexOf(')');
          String ANGLE=s.substring(0,idx);
          Debug.TRACE("TextObject.decodeSVG: X="+X+", Y="+Y+", ANGLE="+ANGLE);
//          this.ANGLE=Double.parseDouble(ANGLE);
          this.ANGLE=Math.toRadians(Double.parseDouble(ANGLE));
        }
      }
    	
    }
    add(MapLocation.newPixelPoint(domTree.getMapGrid(),x,y));
	add(getMapLocation(0).copy());
//	updateSecondPoint();
    justifySecondPoint();
  }
  
  private double getAngle() { return(ANGLE); }
  
  private void setAngle()
  {	MapLocation p0=getMapLocation(0);
 	MapLocation p1=getMapLocation(1);
    double x0=(float)p0.getX();
    double y0=(float)p0.getY();
    double x1=(float)p1.getX();
    double y1=(float)p1.getY();
    // Calculate angle
    double dx=x1-x0;
    double dy=y1-y0;
    float theta=3.14f/8;
//  theta=(float)Math.asin(dy/dx);
    theta=(float)Math.atan2(dy,dx);
    Debug.TRACE("TextObject.getAngle: dx="+dx+", dy="+dy+", rad="+theta+", deg="+Math.toDegrees(theta));
//    return(theta);
    this.ANGLE=theta;
  }
  
  public void paint(Graphics2D g)
  {	MapLocation p0=getMapLocation(0);
    setAngle();
    justifySecondPoint();
    //Get the current transform
    AffineTransform originalTransform=g.getTransform();
    // Perform transformation
    AffineTransform trans=(AffineTransform)originalTransform.clone();
    trans.rotate(getAngle(),(float)p0.getX(),(float)p0.getY());
    g.setTransform(trans);
    // Render
    Util.drawString(g,getText(),(float)p0.getX(),(float)p0.getY(),font,fill,stroke);
    // Restore original transform
    g.setTransform(originalTransform); // Restore original transform
  }
  
  protected void directUpdateSVGElement()
  {	MapLocation p1=getMapLocation(0);
//	MapLocation p2=getMapLocation(1);
    svgElement.setAttributeNS(null,"id",getIdent());
//    svgElement.setAttributeNS(null,"x",""+p1.getX());
//    svgElement.setAttributeNS(null,"y",""+p1.getY());
    double angle=getAngle();
    if(angle!=0)
    {	
      svgElement.setAttributeNS(null,"x","0");
      svgElement.setAttributeNS(null,"y","0");
//      svgElement.setAttributeNS(null,"rotate",""+Math.toDegrees(angle)); // Roterer en og en bokstav !!!
//      svgElement.setAttributeNS(null,"transform","1 0 0 1 0 0");
      String transform="translate("+p1.getX()+","+p1.getY()+") rotate("+Math.toDegrees(angle)+")";	
//      svgElement.setAttributeNS(null,"transform","rotate(30)");
      svgElement.setAttributeNS(null,"transform",transform);
    }
    else
    { svgElement.setAttributeNS(null,"x",""+p1.getX());
      svgElement.setAttributeNS(null,"y",""+p1.getY());	
    }
    svgElement.setTextContent(getText());
    font.appendSVGAttributes(svgElement);
    fill.appendSVGAttributes(svgElement);
    stroke.appendSVGAttributes(svgElement);
  }
  
  
  // ****************************************************************
  // *** INNER CLASS: EditGeneralPanel
  // ****************************************************************
  public JPanel getEditGeneralPanel(String title)
  { return(new EditGeneralPanel(title)); }
  private class EditGeneralPanel extends JPanel
  { static final long serialVersionUID=0; // AD'HOC
    private JTextField identField;
    private JTextField textField;
//    private JButton fontButton;
    private JButton fillButton;
    private JButton strokeButton;
    
    public void paint(Graphics g)
    { Debug.TRACE("TextObject.EditGeneralPanel.paint: ");
      identField.setText(getIdent());
//      fontButton.setBackground(font.getColor());
      fillButton.setBackground(fill.getColor());
      strokeButton.setBackground(stroke.getColor());
  	  super.paint(g);  
    }
  	
    public EditGeneralPanel(String title)
    { setBorder(Util.getTitleBorder(title));
      setPreferredSize(new Dimension(350,50+20+20+20+20));
      setLayout(new GridLayout(5,2));
      add(new JLabel("Ident:"));
      identField=new JTextField(getIdent());
      identField.addActionListener(new ActionListener()
      { public void actionPerformed(ActionEvent e)
        { setIdent(identField.getText()); }
      });
      add(identField);
      add(new JLabel("Text:"));
      textField=new JTextField(getText());
      textField.addActionListener(new ActionListener()
      { public void actionPerformed(ActionEvent e)
        { setText(textField.getText()); }
      });
      add(textField);
      //fontButton=
    	  addEditFontButton(this);
      fillButton=addEditFillButton(this,false);
      strokeButton=addEditStrokeButton(this,false);
    }
  }    

}
